package com.example.springaop.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

/**
 * @author : niu niu
 * @version : 1.0.0
 * @date : 2023/5/7 12:11
 */
@Aspect //定义切面
@Component
public class UserAOP {
    //定义切点
    @Pointcut("execution(* com.example.springaop.controller.UserController.* (..))")
    void pointCut(){}

    //定义通知
    /**
     * 前置通知
     */
    @Before("pointCut()")
    void beforeAdvice(){
        System.out.println("执行了前置通知..");
    }
    /**
     * 后置通知
     */
    @After("pointCut()")
    void afterAdvice(){
        System.out.println("执行后置通知..");
    }
    /**
     * 异常通知
     */
    @AfterThrowing("pointCut()")
    void exceptionAdvice(){
        System.out.println("执行异常通知..");
    }
    /**
     * 返回通知
     */
    @AfterReturning("pointCut()")
    void returnAdvice(){
        System.out.println("执行返回通知..");
    }
    /**
     * 环绕通知
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around("pointCut()")
    Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
        Object object = null;
        System.out.println("进入环绕通知..");
        StopWatch  stopWatch = new StopWatch();
        stopWatch.start();
        object = joinPoint.proceed();
        stopWatch.stop();
        System.out.println(joinPoint.getSignature().getName()+"执行了"+stopWatch.getTotalTimeMillis()+"ms");
        System.out.println("退出环绕通知..");
        return object;
    }
}
